package com.waa.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.waa.gulimall.common.constant.ProductConstant;
import com.waa.gulimall.common.to.GiteeUserInfo;
import com.waa.gulimall.common.utils.HttpUtils;
import com.waa.gulimall.member.dao.MemberLevelDao;
import com.waa.gulimall.member.entity.MemberLevelEntity;
import com.waa.gulimall.member.exception.EmailExsitException;
import com.waa.gulimall.member.exception.UsernameExsitException;
import com.waa.gulimall.member.vo.GiteeAccessToken;
import com.waa.gulimall.member.vo.MemberLoginVo;
import com.waa.gulimall.member.vo.MemberRegistVo;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.waa.gulimall.common.utils.PageUtils;
import com.waa.gulimall.common.utils.Query;

import com.waa.gulimall.member.dao.MemberDao;
import com.waa.gulimall.member.entity.MemberEntity;
import com.waa.gulimall.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Autowired
    private MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void regist(MemberRegistVo memberRegistVo) {
        final MemberEntity memberEntity = new MemberEntity();
        //设置默认等级
        final MemberLevelEntity levelEntity = memberLevelDao.selectOne(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1));
        //存储会员的默认等级
        memberEntity.setLevelId(levelEntity.getId());
        //检查用户名和邮箱是否唯一
        checkEmailUnique(memberRegistVo.getEmail());
        //检查用户名是否是唯一的
        checkUsernameUnique(memberRegistVo.getUserName());
        //密码要进行加密存储
        final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        final String password = passwordEncoder.encode(memberRegistVo.getPassword());
        memberEntity.setPassword(password);
        //存储用户名
        memberEntity.setUsername(memberRegistVo.getUserName());
        //存储邮箱号
        memberEntity.setEmail(memberRegistVo.getEmail());
        //注册时间
        memberEntity.setCreateTime(new Date());
        //保存用户
        this.baseMapper.insert(memberEntity);
    }

    @Override
    public void checkEmailUnique(String email) throws EmailExsitException {
        final Long count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("email", email));
        if (count > 0) {
            throw new EmailExsitException();
        }

    }

    @Override
    public void checkUsernameUnique(String userName) throws UsernameExsitException {
        final Long count = this.baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (count > 0) {
            throw new UsernameExsitException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo memberLoginVo) {
        final String loginacct = memberLoginVo.getLoginacct();
        final String password = memberLoginVo.getPassword();
        //去数据库查
        final MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginacct).or()
                .eq("email", loginacct));
        if (null == memberEntity) {
            //登录失败
            return null;
        } else {
            //1.获取数据库的password
            final String passwordWithDB = memberEntity.getPassword();
            //密码匹配
            final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            final boolean flag = passwordEncoder.matches(password, passwordWithDB);
            if (flag) {
                return memberEntity;
            } else {
                return null;
            }
        }
    }

    @Override
    public MemberEntity login(GiteeAccessToken giteeAccessToken) {
        //根据Token,通过查询Gitee OPen Api获取用户信息
        final HashMap<String, String> query = new HashMap<>();
        query.put("access_token", giteeAccessToken.getAccess_token());
        final HttpResponse response_userInfo;
        GiteeUserInfo userInfo = null;
        try {
            response_userInfo = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", new HashMap<>(), query);
            final String userInfoToString = EntityUtils.toString(response_userInfo.getEntity());
            userInfo = JSON.parseObject(userInfoToString, GiteeUserInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (userInfo!= null) {
            //1.当前用户如果是第一次进入网站，就自动注册（为当前社交用户生成一个会员信息账号，以后这个社交账号就对应指定的会员）
            //根据userInfo中的email和mobile是否存在来判断是否注册了（手机号暂时没写）
            //TODO 社交登录没有完善
            final MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("email", userInfo.getEmail()).or());
            if (null==memberEntity){
                final MemberEntity newMemberEntity = new MemberEntity();
                //为null,说明没有注册
                try {
                    newMemberEntity.setNickname(userInfo.getName());//昵称
                    newMemberEntity.setCreateTime(new Date());//创建时间
                }catch (Exception e){
                }
                newMemberEntity.setEmail(userInfo.getEmail());//邮箱号
                newMemberEntity.setLevelId(Long.valueOf(ProductConstant.MemberLvel.COMMON_MEMBER.getCode()));//设置会员身份
                final int insert = this.baseMapper.insert(newMemberEntity);
                if (insert>0)return memberEntity;
                else throw new RuntimeException("社交登录注册信息异常");
            }else {
             return memberEntity;
            }
        } else {
          throw new RuntimeException("此用户的信息为空（社交登录）");
        }
    }

}